//
//  ModelActor.swift
//  TestConcurreces
//
//  Created by rolodestar on 2025/6/16.
//
import SwiftData
import Foundation


@available(macOS 14,iOS 17, *)
@ModelActor
public actor VideoActor:ObservableObject{
    var activeDownloadTask:[PersistentIdentifier: URLSessionDownloadTask] = [:]
    var storedFolder: URL{
        let url =   FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0]
//        let result =  url.appendingPathComponent("RoDownload", conformingTo: .directory) //.appendPathComponent("RoDownload")
        let result =  url.appending(path: "RoDownload") //.appendPathComponent("RoDownload")
        try! FileManager.default.createDirectory(at: result, withIntermediateDirectories: true)
        return result
    }
    func getModel(by id: PersistentIdentifier) -> any NetVideoProtol{
       let model =  modelContext.model(for: id)
        if let result = model as? (any NetVideoProtol) ,!result.isDeleted{
            return result
            
        }
        fatalError(  "不符合协议的")
//        return modelContext.model(for: id) as! (any NetVideoProtol)
    }
//    public func appendNewVideo(id: UUID = UUID(),remoteUrl: URL) async {
//        viewThread(at: "videoActor - appendNewVideo")
//        let video = VideoModel(id: id, remoteUrl: remoteUrl)
//        do{
//            self.modelContext.insert(video)
//            try self.modelContext.save()
//        }catch{
//            print(error)
//        }
//    }
    public func appendNewVideoAndDownload(model: any NetVideoProtol) async throws{
        try await downloadFile(id: model.persistentModelID)
    }
    public func appendNewVideoAndDownload(id: PersistentIdentifier) async throws{
        let model = getModel(by: id)
        try await downloadFile(id: model.persistentModelID)
    }
    public func checkIsDownload(filePath: URL) -> Bool{
        return FileManager.default.fileExists(atPath: filePath.path())
    }
    
    private func downloadFile(id: PersistentIdentifier) async throws {
        let model = getModel(by: id)
        let url = model.remoteUrl
        let urlRequest = URLRequest(url: url)
        let downloadTask =  URLSession.shared.downloadTask(with: urlRequest)
        downloadTask.delegate = VideoDownloadDelegate(actor: self, videoId: id)
        activeDownloadTask[id] = downloadTask
        
        Task.detached {
            viewThread(at: "videoActor - downloadFile -")
           
            
            downloadTask.resume()
            return try await URLSession.shared.download(from: url)
        }
        
    }
    public func startDownload(id: PersistentIdentifier) async throws{
//        let fetchDes = FetchDescriptor<VideoModel>(predicate: #Predicate { $0.persistentModelID == id })
//        let model = try  modelContext.fetch(fetchDes)[0]
        let model = getModel(by: id)
        let id = model.persistentModelID
        viewThread(at: "videoActor - startDownload")
        do{
            try await downloadFile(id: id)
            
        }catch{
            print(error)
        }
        
    }
    
    public func pauseDownload(id: PersistentIdentifier) async{
        do{
            guard let downloadTask = activeDownloadTask[id] else{ return }
            let resumeData = await downloadTask.cancelByProducingResumeData()
            viewThread(at: "actor - update - download finished")
            let model = getModel(by: id)
            model.resumeData = resumeData
            try self.modelContext.save()
        }catch{
            print(error)
        }
    }
    
    public func resumeDownload(id: PersistentIdentifier) async{
        
            let model = getModel(by: id)
            guard let data = model.resumeData else { return}
        let downloadTask =  URLSession.shared.downloadTask(withResumeData: data)
            
        downloadTask.delegate = VideoDownloadDelegate(actor: self, videoId: id)
            activeDownloadTask[id] = downloadTask
            downloadTask.resume()
        
    }
    
    
    func update(id:PersistentIdentifier,localPath: URL) throws{
        viewThread(at: "actor - update - download finished")
//        let fetchDes = FetchDescriptor<VideoModel>(predicate: #Predicate { $0.persistentModelID == id })
//        let model = try  modelContext.fetch(fetchDes)[0]
        let model = getModel(by: id)
        model.localUrl = localPath
        model.resumeData = nil
        try self.modelContext.save()
    }
    func update(id:PersistentIdentifier,progress: Double) throws{
        if progress == 1.0{
            viewThread(at: "actor - update - progress ")
        }
//        let fetchDes = FetchDescriptor<VideoModel>(predicate: #Predicate { $0.persistentModelID == id })
//        let model = try  modelContext.fetch(fetchDes)[0]
        let model = getModel(by: id)
        model.downloadProgress = progress
        try self.modelContext.save()
    }
}

func viewThread(at: String){
    print("\n\nat \(at),\(Thread.current)\n\n")
}
